﻿using System;
using System.Collections.Generic;
using HtmlTagInnerTextTests.Common;
using WebAndLoadTestPluginsAndRules.Common;
using WebAndLoadTestPluginsAndRules.WebTestPlugins;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.VisualStudio.TestTools.WebTesting;

namespace HtmlTagInnerTextTests
{


    /// <summary>
    ///This is a test class for AppendQueryStringValueTest and is intended
    ///to contain all AppendQueryStringValueTest Unit Tests
    ///</summary>
    [TestClass]
    public class AppendQueryStringValueTest
    {
       


        /// <summary>
        ///A test for GetParameterValue
        ///</summary>
        [TestMethod]
        [Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItem("WebAndLoadTestPluginsAndRules.dll")]
        public void GetParameterValue_WhenUsingFixedValue_EnsureFixedValueIsReturned()
        {
            // Arrange
            IDictionary<string, object> webTestContext = new Dictionary<string, object>();
            string valueContextParameter = string.Empty;
            const string parameterValue = "Testvalue";
            const string expected = parameterValue;

            // Act
            string actual = AppendQueryStringValue_Accessor.GetParameterValue(webTestContext, valueContextParameter, parameterValue);

            // Assert
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for GetParameterValue
        ///</summary>
        [TestMethod]
        [Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItem("WebAndLoadTestPluginsAndRules.dll")]
        public void GetParameterValue_WhenUsingContextValue_EnsureContextValueIsReturned()
        {
            // Arrange
            const string valueContextParameter = "ParameterName";
            const string valueContextParameterValue = "TestValue";
            IDictionary<string, object> webTestContext = new Dictionary<string, object> { { valueContextParameter, valueContextParameterValue } };
            string parameterValue = string.Empty;
            const string expected = valueContextParameterValue;

            // Act
            string actual = AppendQueryStringValue_Accessor.GetParameterValue(webTestContext, valueContextParameter, parameterValue);

            // Assert
            Assert.AreEqual(expected, actual);
        }
        /// <summary>
        ///A test for GetParameterValue
        ///</summary>
        [TestMethod]
        [Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItem("WebAndLoadTestPluginsAndRules.dll")]
        public void GetParameterValue_WhenUsingContextValueWhichIsNull_EnsureEmptyStringIsReturned()
        {
            // Arrange
            const string valueContextParameter = "ParameterName";
            const string valueContextParameterValue = null;
            IDictionary<string, object> webTestContext = new Dictionary<string, object> { { valueContextParameter, valueContextParameterValue } };
            string parameterValue = string.Empty;
            string expected = string.Empty;

            // Act
            string actual = AppendQueryStringValue_Accessor.GetParameterValue(webTestContext, valueContextParameter, parameterValue);

            // Assert
            Assert.AreEqual(expected, actual);
        }
        /// <summary>
        ///A test for GetParameterValue
        ///</summary>
        [TestMethod]
        [Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItem("WebAndLoadTestPluginsAndRules.dll")]
        public void GetParameterValue_WhenParameterDoesNotExist_EnsureWebTestExceptionIsThrown()
        {
            // Arrange
            IDictionary<string, object> webTestContext = new Dictionary<string, object>();
            const string valueContextParameter = "NoSuchValue!";
            const string parameterValue = null;

            // Act
            Action action = () => AppendQueryStringValue_Accessor.GetParameterValue(webTestContext, valueContextParameter, parameterValue);


            // Assert
            AssertHelpers.ThrowsException<WebTestException>(action);
        }


        /// <summary>
        ///A test for GetParameterValue
        ///</summary>
        [TestMethod]
        [Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItem("WebAndLoadTestPluginsAndRules.dll")]
        public void GetParameterValue_WhenContextIsNull_EnsureThrowsArgumentException()
        {
            // Arrange
            const string valueContextParameter = "ParameterName";
            const IDictionary<string, object> webTestContext = null;
            string parameterValue = string.Empty;

            // Act
            Action action = () => AppendQueryStringValue_Accessor.GetParameterValue(webTestContext, valueContextParameter, parameterValue);

            // Assert
            AssertHelpers.ThrowsArgumentException<ArgumentNullException>(action, "webTestContext");
        }

        /// <summary>
        ///A test for Filter
        ///</summary>
        [TestMethod]
        [Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItem("WebAndLoadTestPluginsAndRules.dll")]
        public void Filter_WhenFilterTextNull_EnsureAlwaysTrueFilter()
        {
            // Arrange
            Filter expected = FilterFactory.AlwaysTrue;
            AppendQueryStringValue_Accessor appendQueryStringValue = new AppendQueryStringValue_Accessor
                                                                {
                                                                    FilterText = null,
                                                                };

            // Act
            Filter actual = appendQueryStringValue.Filter;

            // Assert
            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        ///A test for Filter
        ///</summary>
        [TestMethod]
        [Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItem("WebAndLoadTestPluginsAndRules.dll")]
        public void Filter_WhenFilterTextNonNull_EnsureCallingFilterFactory()
        {
            // Arrange
            const string expectedFilterText = "theFilterText";
            const FilterMethod expectedFilterMethod = FilterMethod.Regex;
            const bool expectedIgnoreCase = true;

            bool isCalled = false;

            FakeFilterFactory fakeFilterFactory = new FakeFilterFactory(
                (filterText, filterMethod, ignoreCase) =>
                {
                    isCalled = true;
                    return null;
                }
            );
            AppendQueryStringValue_Accessor appendQueryStringValue = new AppendQueryStringValue_Accessor(fakeFilterFactory)
            {
                FilterText = expectedFilterText,
                FilterMethod = expectedFilterMethod,
                IgnoreCase = expectedIgnoreCase,
            };

            // Act
            Filter actual = appendQueryStringValue.Filter;

            // Assert
            Assert.IsTrue(isCalled);
        }

        /// <summary>
        ///A test for Filter
        ///</summary>
        [TestMethod]
        [Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItem("WebAndLoadTestPluginsAndRules.dll")]
        public void Filter_WhenFilterTextNonNull_EnsureFilterTextIsPassedToFactory()
        {
            // Arrange
            const string expectedFilterText = "theFilterText";
            const FilterMethod expectedFilterMethod = FilterMethod.Regex;
            const bool expectedIgnoreCase = true;

            string actualFilterText = null;

            FakeFilterFactory fakeFilterFactory = new FakeFilterFactory(
                (filterText, filterMethod, ignoreCase) =>
                {
                    actualFilterText = filterText;
                    return null;
                }
            );
            AppendQueryStringValue_Accessor appendQueryStringValue = new AppendQueryStringValue_Accessor(fakeFilterFactory)
            {
                FilterText = expectedFilterText,
                FilterMethod = expectedFilterMethod,
                IgnoreCase = expectedIgnoreCase,
            };

            // Act
            Filter actual = appendQueryStringValue.Filter;

            // Assert
            Assert.AreEqual(expectedFilterText, actualFilterText);
        }

        /// <summary>
        ///A test for Filter
        ///</summary>
        [TestMethod]
        [Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItem("WebAndLoadTestPluginsAndRules.dll")]
        public void Filter_WhenFilterTextNonNull_EnsureFilterMethodIsPassedToFactory()
        {
            // Arrange
            const string expectedFilterText = "theFilterText";
            const FilterMethod expectedFilterMethod = FilterMethod.Regex;
            const bool expectedIgnoreCase = true;

            FilterMethod actualFilterMethod = (FilterMethod)(-1);

            FakeFilterFactory fakeFilterFactory = new FakeFilterFactory(
                (filterText, filterMethod, ignoreCase) =>
                {
                    actualFilterMethod = filterMethod;
                    return null;
                }
            );
            AppendQueryStringValue_Accessor appendQueryStringValue = new AppendQueryStringValue_Accessor(fakeFilterFactory)
            {
                FilterText = expectedFilterText,
                FilterMethod = expectedFilterMethod,
                IgnoreCase = expectedIgnoreCase,
            };

            // Act
            Filter actual = appendQueryStringValue.Filter;

            // Assert
            Assert.AreEqual(expectedFilterMethod, actualFilterMethod);
        }
        /// <summary>
        ///A test for Filter
        ///</summary>
        [TestMethod]
        [Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItem("WebAndLoadTestPluginsAndRules.dll")]
        public void Filter_WhenFilterTextNonNull_EnsureIgnoreCaseIsPassedToFactory()
        {
            // Arrange
            const string expectedFilterText = "theFilterText";
            const FilterMethod expectedFilterMethod = FilterMethod.Regex;
            const bool expectedIgnoreCase = true;

            bool actualIgnoreCase = false;

            FakeFilterFactory fakeFilterFactory = new FakeFilterFactory(
                (filterText, filterMethod, ignoreCase) =>
                {
                    actualIgnoreCase = ignoreCase;
                    return null;
                }
            );
            AppendQueryStringValue_Accessor appendQueryStringValue = new AppendQueryStringValue_Accessor(fakeFilterFactory)
            {
                FilterText = expectedFilterText,
                FilterMethod = expectedFilterMethod,
                IgnoreCase = expectedIgnoreCase,
            };

            // Act
            Filter actual = appendQueryStringValue.Filter;

            // Assert
            Assert.AreEqual(expectedIgnoreCase, actualIgnoreCase);
        }

        /// <summary>
        ///A test for PreRequest
        ///</summary>
        [TestMethod]
        [Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItem("WebAndLoadTestPluginsAndRules.dll")]
        public void PreRequest_WhenFilterMatches_EnsureParameterIsAdded()
        {
            // Arrange
            WebTestRequest request = new WebTestRequest("http://www.example.com");
            IDictionary<string, object> context = new Dictionary<string, object>();
            const string parameterName = "name";
            const string parameterValue = "value";
            QueryStringParameterCollection expectedParameters = new QueryStringParameterCollection { { parameterName, parameterValue } };
            AppendQueryStringValue_Accessor target = new AppendQueryStringValue_Accessor
                                                         {
                                                             FilterText = "",
                                                             Name = parameterName,
                                                             Value = parameterValue,
                                                         };

            // Act
            target.PreRequest(request, context);

            // Assert
            AssertHelpers.AssertCollectionsEqual(expectedParameters, request.QueryStringParameters);
        }

        /// <summary>
        ///A test for PreRequest
        ///</summary>
        [TestMethod]
        [Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItem("WebAndLoadTestPluginsAndRules.dll")]
        public void PreRequest_WhenFilterDoesNotMatch_EnsureParameterIsNotAdded()
        {
            // Arrange
            WebTestRequest request = new WebTestRequest("http://www.example.com");
            IDictionary<string, object> context = new Dictionary<string, object>();
            const string parameterName = "name";
            const string parameterValue = "value";
            QueryStringParameterCollection expectedParameters = new QueryStringParameterCollection();
            AppendQueryStringValue_Accessor target = new AppendQueryStringValue_Accessor
            {
                FilterText = "Do Not Match!",
                FilterMethod = FilterMethod.ExactMatch,
                Name = parameterName,
                Value = parameterValue,
            };

            // Act
            target.PreRequest(request, context);

            // Assert
            AssertHelpers.AssertCollectionsEqual(expectedParameters, request.QueryStringParameters);
        }
    }
}